//
//  DTKMapBundleMapJSAPI.m
//  DTKMapBundle
//
//  Created by 张概 on 2024/3/7.
//

#import "DTKMapBundleMapJSAPI.h"
#import <AMapLocationKit/AMapLocationKit.h>
#import "LocationUtil.h"
#import "DTKMapBundle.h"
#import "SearchMapViewController.h"
#import "MapPreviewViewController.h"
#import "OpenMapParam.h"
#import "DTKImagePicker.h"
#import <SystemConfiguration/CaptiveNetwork.h>
#import <CoreLocation/CoreLocation.h>
#import <AMapLocationKit/AMapLocationKit.h>
#import <AMapFoundationKit/AMapFoundationKit.h>
@interface DTKMapBundleMapJSAPI()<AMapLocationManagerDelegate, CLLocationManagerDelegate>
@property(nonatomic,copy)void (^callBack)(NSDictionary *);
@property(nonatomic,strong)CLLocationManager *gpsLocationManager;
@end

@implementation DTKMapBundleMapJSAPI

+ (NSArray<NSString *> *)apiNameList {
    return @[@"getLocation", @"openLocation", @"chooseImage", @"getWifiInfo", @"getDeviceInfo", @"getGeolocation", @"getGPSLocation", @"toSetPage", @"getGeoKey"];
}

- (void)handleRequest:(id<DTKExternalAPIRequest>)request
          withContext:(id<DTKExternalJSAPIContext>)context
             callback:(DTKExternalAPICallback)callback {
    NSString *apiName = request.apiName;
    NSDictionary *params = request.plainJSParams;
    if ([apiName isEqualToString:@"getLocation"]) {
        //获取定位
        [self getLocation:params callBack:callback];
    } else if ([apiName isEqualToString:@"openLocation"]) {
        //打开地图预览
        [self openLocation:params callBack:callback];
    } else if ([apiName isEqualToString:@"chooseImage"]) {
        //选取图片上传
        [self chooseImage:params callBack:callback];
    } else if ([apiName isEqualToString:@"getWifiInfo"]) {
        //获取正在连接的WIFI信息
        [self getConnectedWifiInfo:callback];
    } else if ([apiName isEqualToString:@"getDeviceInfo"]) {
        //获取设备信息
        [self getDeviceInfo: callback];
    } else if ([apiName isEqualToString:@"getGeolocation"]) {
        CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
        if (status == kCLAuthorizationStatusDenied) {
            //直接报错
            NSDictionary *data = @{
                @"errorCode": @"11",
                @"errorMessage": @"请确认定位相关权限已开启",
                @"result": @{
                    @"errCode": @11,
                    @"errMsg": @"请确认定位相关权限已开启"
                }
            };
            if (callback) {
                callback(data);
            }
            return;
        } else {
            AMapLocationManager *locationManager = [LocationUtil shareInstance].locationManager;
            locationManager.distanceFilter = kCLDistanceFilterNone;
            locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
            locationManager.pausesLocationUpdatesAutomatically = YES;
            [locationManager requestLocationWithReGeocode:YES completionBlock:^(CLLocation *location, AMapLocationReGeocode *regeocode, NSError *error) {
                if (error) {
                    NSDictionary *data = @{
                        @"errorCode": @(error.code),
                        @"errorMessage": error.localizedDescription,
                        @"result": @{
                            @"errCode": @(error.code),
                            @"errMsg": error.localizedDescription
                        }
                    };
                    callback(data);
                } else {
                    NSDictionary *result = @{
                        @"latitude": [NSNumber numberWithDouble:location.coordinate.latitude],
                        @"longitude": [NSNumber numberWithDouble:location.coordinate.longitude],
                        @"accuracy": @(location.horizontalAccuracy),
                        @"address": regeocode.formattedAddress,
                        @"district": regeocode.district,
                        @"province": regeocode.province,
                        @"road": regeocode.street
                    };
                    callback(result);
                }
            }];
        }
    } else if ([apiName isEqualToString:@"getGPSLocation"]) {
        [self getGPSLocation:params callBack:callback];
    } else if ([apiName isEqualToString:@"toSetPage"]) {
        [[UIApplication sharedApplication]openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString] options:@{} completionHandler:^(BOOL finished){
            
        }];
    } else if ([apiName isEqualToString:@"getGeoKey"]) {
        if (callback) {
            callback(@{@"geoKey": [AMapServices sharedServices].apiKey});
        }
    }
}

-(void)getGPSLocation:(NSDictionary *)params callBack:(DTKExternalAPICallback)callback {
    if (self.gpsLocationManager == nil) {
        self.gpsLocationManager = [[CLLocationManager alloc]init];
        self.gpsLocationManager.delegate = self;
        self.gpsLocationManager.distanceFilter = 15;
        self.gpsLocationManager.desiredAccuracy = kCLLocationAccuracyBest;
        self.gpsLocationManager.pausesLocationUpdatesAutomatically = YES;
    }
    CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
    if (status == kCLAuthorizationStatusDenied) {
        //直接报错
        NSDictionary *data = @{
            @"errorCode": @"11",
            @"errorMessage": @"请确认定位相关权限已开启",
            @"result": @{
                @"errCode": @11,
                @"errMsg": @"请确认定位相关权限已开启"
            }
        };
        if (callback) {
            callback(data);
        }
        return;
    } else {
        self.callBack = callback;
        [self.gpsLocationManager requestWhenInUseAuthorization];
        [self.gpsLocationManager requestLocation];
    }
}

//获取地理定位
-(void)getLocation:(NSDictionary *)params callBack:(DTKExternalAPICallback)callback {
    NSInteger targetAccuracy = [params[@"targetAccuracy"] integerValue];//精度，单位米
    BOOL withReGeocode = [params[@"withReGeocode"] boolValue];//是否需要带有逆地理编码信息
    AMapLocationManager *locationManager = [LocationUtil shareInstance].locationManager;
    locationManager.distanceFilter = kCLDistanceFilterNone;
    if (targetAccuracy <= 10) {
        locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
    } else if (targetAccuracy <= 100) {
        locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
    } else if (targetAccuracy <= 1000) {
        locationManager.desiredAccuracy = kCLLocationAccuracyKilometer;
    } else {
        locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers;
    }
    locationManager.pausesLocationUpdatesAutomatically = YES;
    locationManager.allowsBackgroundLocationUpdates = NO;
    [locationManager requestLocationWithReGeocode:withReGeocode completionBlock:^(CLLocation *location, AMapLocationReGeocode *regeocode, NSError *error) {
        if (error) {
            if (callback) {
                callback(error);
            }
        } else {
            NSMutableDictionary *result = [@{
                @"latitude": @(location.coordinate.latitude),
                @"longitude": @(location.coordinate.longitude)
            } mutableCopy];
            if (regeocode) {
                result[@"province"] = regeocode.province;
                result[@"city"] = regeocode.city;
                result[@"district"] = regeocode.district;
                result[@"address"] = regeocode.formattedAddress;
            }
            result[@"accuracy"] = @(targetAccuracy);
            if (callback) {
                callback(result);
            }
            
        }
    }];
}
//打开地图
-(void)openLocation:(NSDictionary *)params callBack:(DTKExternalAPICallback)callback {
    NSString *title = params[@"title"];
    NSString *address = params[@"address"];
    CGFloat latitude = [params[@"latitude"] floatValue];
    CGFloat longitude = [params[@"longitude"] floatValue];
    NSInteger scope = [params[@"scope"] integerValue];
    OpenMapParam *param = [[OpenMapParam alloc]init];
    param.title = title;
    param.address = address;
    param.location = [[CLLocation alloc]initWithLatitude:latitude longitude:longitude];
    param.scope = scope;
    MapPreviewViewController *mapVC = [[MapPreviewViewController alloc]init];
    mapVC.info = param;
    [[[DTKMapBundle services]uiHierachyService].currentTopViewController presentViewController:mapVC animated:YES completion:nil];
}
//选择图片上传
-(void)chooseImage:(NSDictionary *)params callBack:(DTKExternalAPICallback)callback {
    NSInteger count = [params[@"count"] integerValue];//必传
    NSString *sourceType = params[@"sourceType"]; // @"camera", @"album",非必传
    BOOL compress = [params[@"compress"] boolValue]; //非必传，是否压缩
    DTKImagePicker *picker = [DTKImagePicker sharedInstance];
    if ([sourceType isEqualToString:@"camera"]) {
        [picker takePhoto:^(id  _Nullable responseData) {
            NSMutableArray *array = [NSMutableArray array];
            for (UIImage *image in responseData) {
                NSData *data;
                if (compress) {
                    data = UIImageJPEGRepresentation(image, 0.2);
                } else {
                    data = UIImageJPEGRepresentation(image, 0.8);
                }
                NSString *base64 = [data base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
                [array addObject:base64];
            }
            if (callback) {
                callback(array);
            }
        }];
    } else {
        [picker pickPhotos:count completion:^(id  _Nullable responseData) {
            NSMutableArray *array = [NSMutableArray array];
            for (UIImage *image in responseData) {
                NSData *data;
                if (compress) {
                    data = UIImageJPEGRepresentation(image, 0.2);
                } else {
                    data = UIImageJPEGRepresentation(image, 0.8);
                }
                NSString *base64 = [data base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
                [array addObject:base64];
            }
            if (callback) {
                callback(array);
            }
        }];
    }
}
//获取正在连接的Wifi信息
-(void)getConnectedWifiInfo:(DTKExternalAPICallback)callback {
    CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
    switch (status) {
        case kCLAuthorizationStatusAuthorizedAlways:
        case kCLAuthorizationStatusAuthorizedWhenInUse:
        case kCLAuthorizationStatusRestricted:
        {
            NSArray *ifs = (__bridge_transfer id)CNCopySupportedInterfaces();
            NSMutableArray *wifiList = [NSMutableArray array];
            for (NSString *ifnam in ifs) {
                NSMutableDictionary *param = [NSMutableDictionary dictionary];
                NSDictionary *info = (__bridge_transfer id)CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifnam);
                if (info[@"SSID"]) {
                    param[@"isConnect"] = @(YES);
                    param[@"ssid"] = info[@"SSID"];
                }
                if (info[@"BSSID"]) {
                    param[@"mac"] = info[@"BSSID"];
                }
                [wifiList addObject:param];
                break;
            }
            if (callback) {
                callback(@{@"wifiList": wifiList});
            }
        }
            break;
        default:
        {
            if (callback) {
                NSDictionary *data = @{
                    @"errorCode": @"11",
                    @"errorMessage": @"请确认定位相关权限已开启",
                    @"result": @{
                        @"errCode": @11,
                        @"errMsg": @"请确认定位相关权限已开启"
                    }
                };
                callback(data);
            }
        }
            break;
    }
}

-(void)getDeviceInfo:(DTKExternalAPICallback)callback {
    NSString *deviceID = [SSKeychain passwordForService:@"DeviceID" account:@"DeviceID"];
    if (deviceID == nil) {
        deviceID = [[[UIDevice currentDevice]identifierForVendor]UUIDString];
        [SSKeychain setPassword:deviceID forService:@"DeviceID" account:@"DeviceID"];
    }
    NSString *brand = @"iPhone";
    NSString *model = [[UIDevice currentDevice]model];
    NSString *systemName = @"iOS";
    NSString *systemVersion = [[UIDevice currentDevice]systemVersion];
    NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
    NSString *appName = [infoDictionary objectForKey:@"CFBundleDisplayName"];
    NSString *appVersion = [infoDictionary objectForKey:@"CFBundleShortVersionString"];
    if (callback) {
        callback(@{
            @"deviceId": deviceID,
            @"brand": brand,
            @"model": model,
            @"systemName": systemName,
            @"systemVersion": systemVersion,
            @"appName": appName,
            @"appVersion": appVersion
        });
    }
}

- (void)amapLocationManager:(AMapLocationManager *)manager didUpdateLocation:(CLLocation *)location reGeocode:(AMapLocationReGeocode *)reGeocode{
    
}

#pragma Mark -- CLLocationManagerDelegate

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
    CLLocation *location = [locations lastObject];
    if (location && self.callBack) {
        NSDictionary *data = @{
            @"lat": @(location.coordinate.latitude),
            @"lon": @(location.coordinate.longitude),
            @"time": @(location.timestamp.timeIntervalSince1970)
        };
        self.callBack(data);
        self.callBack = nil;
    }
}

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
    NSDictionary *data = @{
        @"errorCode": @"11",
        @"errorMessage": @"请确认定位相关权限已开启",
        @"result": @{
            @"errCode": @11,
            @"errMsg": @"请确认定位相关权限已开启"
        }
    };
    if (self.callBack) {
        self.callBack(data);
        self.callBack = nil;
    }
}

@end
